package com.core.toolkit;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.core.mapper.ReservationMapper;
import com.core.pojo.SeatReservation.Enum.ReservationStatusEnum;
import com.core.pojo.SeatReservation.entity.Reservation;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

import static com.core.constant.OtherConstants.DATA_RETENTION_DAYS;
import static com.core.constant.OtherConstants.MAX_DAYS_AHEAD;

/**
 * 每日凌晨任务实现（更新每日教室可用表和每日座位状态表）
 */
@Component
public class DailyDataGenerator {

    @Autowired
    ReservationMapper reservationMapper;
    @Autowired
    private JdbcTemplate jdbcTemplate;

    /**
     * 每天凌晨00:05执行，维护预约数据
     * 1. 生成新一天的可预约数据
     * 2. 清理过期数据
     */
    @Scheduled(cron = "0 5 0 * * ?")
    @Transactional
    public void performDailyMaintenance() {
        // 步骤1：生成新一天的数据
        generateNextDayData();
        // 步骤2：清理过期数据
        purgeExpiredData();
        // 步骤3：修改过期未签到的预约记录
        expiredReservation();
    }

    /**
     * 生成未来第15天的可预约数据
     */
    private void generateNextDayData() {
        // 1. 确定要生成的日期（今天+15天）
        LocalDate nextDate = LocalDate.now().plusDays(MAX_DAYS_AHEAD);

        // 2. 检查该日期数据是否已存在
        Integer count = jdbcTemplate.queryForObject(
                "SELECT COUNT(*) FROM daily_classroom_availability WHERE date = ?",
                Integer.class, nextDate.toString());

        if (count == null || count == 0) {
            // 3. 获取所有教室和座位
            List<Long> classroomIds = getClassroomIds();
            List<Long> seatIds = getSeatIds();

            // 4. 准备批量插入数据
            List<Object[]> availabilityBatch = new ArrayList<>();
            List<Object[]> seatStatusBatch = new ArrayList<>();
            String dateStr = nextDate.toString();

            // 为每个教室添加每日可用数据
            for (Long classroomId : classroomIds) {
                Integer capacity = jdbcTemplate.queryForObject(
                        "SELECT capacity FROM classroom WHERE id = ?",
                        Integer.class, classroomId);

                availabilityBatch.add(new Object[]{classroomId, dateStr, capacity});
            }

            // 为每个座位添加每日状态数据
            for (Long seatId : seatIds) {
                seatStatusBatch.add(new Object[]{seatId, dateStr, "AVAILABLE"});
            }

            // 5. 执行批量插入
            jdbcTemplate.batchUpdate(
                    "INSERT INTO daily_classroom_availability (classroom_id, date, available) VALUES (?, ?, ?)",
                    availabilityBatch
            );

            jdbcTemplate.batchUpdate(
                    "INSERT INTO daily_seat_status (seat_id, date, status) VALUES (?, ?, ?)",
                    seatStatusBatch
            );

            System.out.println("已生成" + nextDate + "的预约数据");
        } else {
            System.out.println(nextDate + "的数据已存在，跳过生成");
        }
    }

    /**
     * 清理过期数据
     */
    private void purgeExpiredData() {
        LocalDate purgeDate = LocalDate.now().minusDays(DATA_RETENTION_DAYS);
        String dateStr = purgeDate.toString();

        // 1. 清理每日教室可用表
        int availabilityCount = jdbcTemplate.update(
                "DELETE FROM daily_classroom_availability WHERE date < ?",
                dateStr
        );

        // 2. 清理每日座位状态表
        int seatStatusCount = jdbcTemplate.update(
                "DELETE FROM daily_seat_status WHERE date < ?",
                dateStr
        );

        System.out.printf("已清理%d天前的数据：删除教室可用记录%d条，座位状态记录%d条%n",
                DATA_RETENTION_DAYS, availabilityCount, seatStatusCount);
    }

    private List<Long> getClassroomIds() {
        return jdbcTemplate.queryForList(
                "SELECT id FROM classroom", Long.class
        );
    }

    private List<Long> getSeatIds() {
        return jdbcTemplate.queryForList(
                "SELECT id FROM seat", Long.class
        );
    }

    /**
     * 修改预约状态
     */
    private void expiredReservation(){
        LocalDate localDate = LocalDate.now().minusDays(1);
        UpdateWrapper<Reservation> updateWrapper=new UpdateWrapper<>();
        updateWrapper.eq("date", localDate).set("status", ReservationStatusEnum.EXPIRED);
        reservationMapper.update(updateWrapper);
    }
}
